import Vue from "vue"
import Vuex from "vuex"
import { INCREMENT, } from "./mutations-types"

// 1.安装vuex插件
Vue.use(Vuex)

// 抽离模块
const moduleA = {
    state: {
        name: 'zhangsan'
    },
    mutations: {
        updateName(state, payload) {
            state.name = payload
        }
    },
    getters: {
        fullName0(state) {
            return state.name + "-kuangtu"
        },
        fullName1(state, getters) {
            return getters.fullName0 + "-fawai"
        },
        fullName2(state, getters, rootState) {
            return getters.fullName1 + rootState.count
        }
    },
    actions: {
        aUpdateName(context) {
            // moudle中的actions只会commit自己的mutations中的函数
            setTimeout(() => {
                context.commit('updateName', 'wangwu')
            }, 3000);
        }
    }
}

// 2.创建对象
const store = new Vuex.Store({
    state: {
        // 定义状态
        count: 0,
        students: [
            { id: 100, name: 'cgs', age: 18 },
            { id: 101, name: 'cgs1', age: 19 },
            { id: 102, name: 'cgs2', age: 20 },
        ],
        info: {
            name: 'cgsthtm',
            age: 1,
            sex: 'male',
            height: 163, // 此属性，为了测试mutations中的异步操作，为了验证mutations中异步操作不能实际修改state中管理的状态，而只是单纯的响应式显示
            level: 1 // 此属性，为了测试actions中调用异步操作
        }
    },
    mutations: {
        // 不要在mutations中使用异步操作（所有函数都应是同步的），否则会造成：界面的值虽然已经修改了，但是实际上state中管理的状态没有改变
        // 管理状态
        [INCREMENT](state) {
            state.count++
        },
        decrement(state) {
            state.count--
        },
        // mutations的payload，也就是携带参数
        incrementCount(state, num) {
            state.count += num
        },
        addStudent(state, stu) {
            state.students.push(stu);
        },
        updateInfo(state) {
            state.info.age = 2 // 修改后可以响应式显示
            // 视频中说：修改后不可以响应式，但实际上已经给该状态增加了address属性和值
            // 但经过实际测试，使用state.info["address"] = "Qinghuangdao" 可以做到响应式
            // 猜测，可能是由于vue版本问题，视频是2018年的，当时的vue版本可能确实存在该问题，后续版本应该做了优化
            state.info["address"] = "Qinghuangdao"
            Vue.set(state.info, "birth", "1999-09-09") // 视频中，该方式可以做到响应式
            // 视频中说：修改后不可以响应式，但实际上已经给该状态删除了name属性和值
            // 但经过实际测试，使用delete state.info.name 可以做到响应式
            // 猜测，可能是由于vue版本问题，视频是2018年的，当时的vue版本可能确实存在该问题，后续版本应该做了优化
            delete state.info.name
            Vue.delete(state.info, 'sex') // 视频中，该方式可以做到响应式
            setTimeout(() => {
                state.info.height = 173 // 在mutations中使用异步，会导致问题：界面的值虽然已经修改了，但是实际上state中管理的状态没有改变
            }, 3000)
            state.info.level = 99
        }
    },
    actions: {
        // 网络请求等异步操作
        aUpdateInfo(context, payload) {
            // setTimeout(() => {
            //     context.commit('updateInfo')
            //     // 一般认为只要commit成功执行了，就说明操作完成了
            //     console.log(payload.message); // actions传递的参数
            //     payload.success() // 调用回调
            // }, 3000)

            // 使用Promise，更优雅的方式
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    context.commit('updateInfo')
                    console.log(payload)
                    resolve('11111')
                }, 3000);
            })
        }
    },
    getters: {
        // 类似计算属性computed，computed适用于：当data中定义的某些数据的展示需要经过一系列处理变化的时候，可以用计算属性
        // 例如：
        powerCount(state) {
            return state.count * state.count
        },
        more20Stu(state) {
            return state.students.filter(s => s.age >= 19)
        },
        more20StuLen(state, getters) {
            return getters.more20Stu.length
        },
        moreAgeStu(state) {
            // 返回函数，供组件调用，例如：返回组件指定条件的数据
            return (age) => state.students.filter(s => s.age >= age)
        }
    },
    modules: {
        a: moduleA,
        b: {
            state: {

            },
            mutations: {

            },
            getters: {

            },
            actions: {

            }
        }
    }
})

// 3.导出对象
export default store

// 对象的解构
const obj = {
    name: 'cgs',
    age: 18,
    sex: 'male',
    address: 'Qinhuangdao'
}
const { name, sex, age } = obj
console.log(name)
console.log(sex)
console.log(age)